package com.mlnx.yingbaisui.device.utils;

import com.mlnx.yingbaisui.device.SleepDto;

import java.io.*;
import java.math.BigInteger;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.*;

public class HealthReadThread implements Runnable {

//    public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private Socket socket;

    public HealthReadThread(Socket socket) {
        this.socket = socket;
    }

    private static String message = "";

    @Override
    public void run() {
        try {
            //输入
            InputStream inPutStream = socket.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(inPutStream);
//            BufferedReader br = new BufferedReader(new InputStreamReader(inPutStream));
            //输出
            OutputStream outputStream = socket.getOutputStream();
            BufferedOutputStream bw = new BufferedOutputStream(outputStream);

            String ip = socket.getInetAddress().getHostAddress();
            int port = socket.getPort();

            String str =  HealthCare.sendServiceTime(true);
//            System.out.println(Thread.currentThread().getId() + "线程: " + "向ip地址:" + ip + " 端口地址:" + port + " 发送数据:" + str);
            bw.write(StringUtils.getByteByString(str));
            bw.flush();
//            System.out.println(Thread.currentThread().getId() + "线程: " + "向ip地址:" + ip + " 端口地址:" + port + " 发送数据:" + str);
//            bw.write(StringUtils.getByteByString(str));
//            bw.flush();

            String readStr = "";
//            char[] buf;
            byte[] buf;
            int readLen = 0;
            while (true) {
                if (socket.isClosed()) {
                    break;
                }
//                buf = new char[1024];
                buf = new byte[1024];
                try {
//                    readLen = br.read(buf);
//                    readStr = new String(buf, 0, readLen);
                    readLen = bis.read(buf);
                    if (readLen <= 0) {
//                        System.out.println(Thread.currentThread().getId() + "线程: " + "ip地址:" + ip + " 端口地址:" + port + "暂无接收数据");
                        continue;
                    }
//                    System.out.println(Thread.currentThread().getId() + "线程: " + "ip地址:" + ip + " 端口地址:" + port + " 接收到原始命令长度:" + readLen);
                    readStr = StringUtils.byteToHexString(buf, readLen);
//                    readStr = new String(buf ,0 , readLen);
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                    socket.close();
//                    continue;
                }
                if (readStr == null || "".equals(readStr)) {
                    continue;
                }

                //获取二进制流 转16进制
//                readStr = Integer.toHexString(Integer.parseInt(readStr, 2));

//                System.out.println(sdf.format(new Date()));
//                System.out.println(Thread.currentThread().getId() + "线程: " + "ip地址:" + ip + " 端口地址:" + port + " 接收到十六进制命令:" + readStr);
//                System.out.print(Thread.currentThread().getId() + "线程: " + "接收ip地址:" + ip + " 端口地址:" + port + " ");

                message += readStr;
                //命令以55aa开头
                //去除前部不完整数据
                message = message.substring(message.indexOf("55aa"));


                List<String> msgList = check(message);

                for (String msg : msgList) {
                    handlerMsg(msg, bw);
                }
            }
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public synchronized static List<String> check(String s) {
        List<String> resultList = new ArrayList<>();
        if (s.length() > 12) {
            int len = Integer.parseInt(s.substring(6,8), 16) * 2;
            if (s.length() < (12 + len)) {
                message = s;
            }
            else if (s.length() > (12 + len)) {
                //最后一个包数据完整
                resultList.add(s.substring(0, 12 + len));
                resultList.addAll(check(s.substring(12 + len)));
            }
            else {
                resultList.add(s.substring(0, 12 + len));
                message = "";
            }
        }
        else {
            message = s;
        }
        return resultList;
    }

    private SleepDto handlerMsg(String msg, BufferedOutputStream bw) {
        SleepDto sleepDto = null;
        List<Object> paramList = StringUtils.unpackCheck(msg);
        if (paramList.size() == 1) {
            HashMap<String, Object> map= (HashMap)paramList.get(0);
            switch (map.get("commandNumber").toString()) {
                case "30" :
                    sleepDto = receiveDetectionResult(map.get("data").toString());
                    System.out.println("————————————收到的数据包解析后如下对象————————————");
                    System.out.println(sleepDto);
                    break;
                default:
                    System.out.println( "命令: " + map.get("commandNumber").toString() +"该命令已被屏蔽或暂不支持该命令");
            }

            //设备初始化与重启 断开链接
            if ("02".equals(map.get("commandNumber").toString()) || "04".equals(map.get("commandNumber").toString())) {
                System.out.println(Thread.currentThread().getId() + "线程: " + "设备初始化与重启 断开链接");
                return null;
            }
        }
        else if (paramList.size() > 1) {
            HashMap<String, Object> map= (HashMap)paramList.get(0);
            if ("03".equals(map.get("commandNumber").toString())) {
                String time = HealthCare.sendServiceTime(false);
                try {
                    bw.write(StringUtils.getByteByString(time));
                    bw.flush();
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
        }
        else {
            System.out.println(Thread.currentThread().getId() + "线程: " + "命令不正确 请重新输入");
        }

        return sleepDto;

    }
    private  SleepDto receiveDetectionResult(String data) {
        SleepDto sleepDto = new SleepDto();
        sleepDto.setDeviceId( data.substring(0, 12));
        sleepDto.setHeartRate(Integer.parseInt(data.substring(12, 14), 16));
        sleepDto.setRespiratoryRate(Integer.parseInt(data.substring(14, 16), 16));
        sleepDto.setBodyExistStatus(Integer.parseInt(data.substring(16, 18), 16));
        sleepDto.setBodyStatus(Integer.parseInt(data.substring(18, 20), 16));
        sleepDto.setMinDistanceTarget(Integer.parseInt(data.substring(20, 24), 16));
        sleepDto.setSignExceptionWarn(Integer.parseInt(data.substring(24, 26), 16));
        //把16进制转浮点类型 并保留2为小数
        sleepDto.setSignalStrength(Float.intBitsToFloat(new BigInteger(data.substring(26, 34), 16).intValue()));
        sleepDto.setInTime(Integer.parseInt(data.substring(34, 38), 16));
        sleepDto.setOffTime(Integer.parseInt(data.substring(38, 42),16));
        sleepDto.setHour(Integer.parseInt(data.substring(48, 50),16));
        sleepDto.setMinute(Integer.parseInt(data.substring(50, 52),16));
        sleepDto.setSecond(Integer.parseInt(data.substring(52, 54),16));
        return sleepDto;
    }
}
